package com.shadow.demo.dictionary.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.*;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.*;

/**
 * 数据转换类
 *
 * @author penggch
 */
@Slf4j
public class ParseUtil {

    private static Method OracleTimeStampMethod = null;

    private static final String REGEX_SPLIT_NUM = "[^0-9\\.\\-]+";

    private static boolean isOracleTimeStamp(Object value) {
        return value != null && "oracle.sql.TIMESTAMP".equals(value.getClass().getName());
    }

    public static Boolean getBoolean(Object obj, Boolean defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof Boolean || obj.getClass().getName().equals(boolean.class.getName())) {
            return (Boolean) obj;
        } else if (obj instanceof Number) {
            return !((Number) obj).equals(0);
        } else {
            return obj.toString().equals("1") || obj.toString().toLowerCase().equals("true");
        }
    }

    public static Short getShort(Object obj, Short defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof Short || obj.getClass().getName().equals(short.class.getName())) {
            return (Short) obj;
        } else if (obj instanceof Number) {
            return ((Number) obj).shortValue();
        } else if (obj instanceof Boolean || obj.getClass().getName().equals(boolean.class.getName())) {
            return ((Boolean) obj) ? (short) 1 : (short) 0;
        } else if (obj instanceof Date) {
            return Long.valueOf(((Date) obj).getTime()).shortValue();
        } else if (isOracleTimeStamp(obj)) {
            Date date = getDate(obj, null);
            return getShort(date, defaultValue);
        } else {
            try {
                String strValue = obj.toString();
                strValue = strValue.replace(",", "");
                if (strValue.length() == 0) {
                    return defaultValue;
                } else if (strValue.indexOf(".") != -1) {
                    return getShort(getDouble(strValue, null), defaultValue);
                } else {
                    return Short.parseShort(strValue);
                }
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    public static short[] getShorts(Object obj, short[] defaultValue) {
        short[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof short[]) {
                result = (short[]) obj;
            } else if (obj instanceof Short[]) {
                Short[] a = (Short[]) obj;
                result = new short[a.length];
                for (int i = 0; i < a.length; i++) {
                    result[i] = a[i];
                }
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new short[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getShort(Array.get(obj, i), null);
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new short[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getShort(ja.get(i), null);
                }
            } else {
                result = getShorts(getShortArray(obj, null), defaultValue);
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Short[] getShortArray(Object obj, Short[] defaultValue) {
        Short[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof Short[]) {
                result = (Short[]) obj;
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new Short[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getShort(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new Short[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getShort(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new Short[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getShort(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                str = str.trim();
                if (str.startsWith("[") && str.endsWith("]")) {
                    JSONArray ja = JSON.parseArray(str);
                    return getShortArray(ja, defaultValue);
                } else {
                    String[] sa = str.split(REGEX_SPLIT_NUM);
                    result = new Short[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getShort(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Byte getByte(Object obj, Byte defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof Byte || obj.getClass().getName().equals(byte.class.getName())) {
            return (Byte) obj;
        } else if (obj instanceof Number) {
            return ((Number) obj).byteValue();
        } else if (obj instanceof Boolean || obj.getClass().getName().equals(boolean.class.getName())) {
            return ((Boolean) obj) ? (byte) 1 : (byte) 0;
        } else if (obj instanceof Date) {
            return Long.valueOf(((Date) obj).getTime()).byteValue();
        } else if (isOracleTimeStamp(obj)) {
            Date date = getDate(obj, null);
            return getByte(date, defaultValue);
        } else {
            try {
                String strValue = obj.toString();
                strValue = strValue.replace(",", "");
                if (strValue.length() == 0) {
                    return defaultValue;
                } else if (strValue.indexOf(".") != -1) {
                    return getByte(getDouble(strValue, null), defaultValue);
                } else {
                    return Byte.parseByte(strValue);
                }
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    public static byte[] getBytes(Object obj, byte[] defaultValue) {
        byte[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof byte[]) {
                result = (byte[]) obj;
            } else if (obj instanceof Byte[]) {
                Byte[] a = (Byte[]) obj;
                result = new byte[a.length];
                for (int i = 0; i < a.length; i++) {
                    result[i] = a[i];
                }
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new byte[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getByte(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new byte[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getByte(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new byte[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getByte(ja.get(i), null);
                }
            } else if (obj instanceof InputStream) {
                result = IoUtil.readByte((InputStream) obj);

            } else if (obj instanceof File) {
                result = IoUtil.readByte((File) obj);

            } else if (obj instanceof ByteArrayOutputStream) {
                result = ((ByteArrayOutputStream) obj).toByteArray();

            } else if (obj instanceof String) {
                String strValue = (String) obj;
                File file = new File(strValue);
                if (file.isFile() && file.exists()) {
                    result = IoUtil.readByte(strValue);

                } else if (strValue.startsWith("[") && strValue.endsWith("]")) {
                    JSONArray ja = JSON.parseArray(strValue);
                    return getBytes(ja, defaultValue);
                } else {
                    String[] sa = strValue.split(REGEX_SPLIT_NUM);
                    result = new byte[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getByte(sa[i].trim(), null);
                    }
                }
            } else {
                result = getBytes(getByteArray(obj, null), defaultValue);
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Byte[] getByteArray(Object obj, Byte[] defaultValue) {
        Byte[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof Byte[]) {
                result = (Byte[]) obj;
            } else if (obj instanceof InputStream) {
                return getByteArray(IoUtil.readByte((InputStream) obj), defaultValue);
            } else if (obj instanceof File) {
                return getByteArray(IoUtil.readByte((File) obj), defaultValue);
            } else if (obj instanceof ByteArrayOutputStream) {
                return getByteArray(((ByteArrayOutputStream) obj).toByteArray(), defaultValue);
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new Byte[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getByte(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new Byte[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getByte(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new Byte[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getByte(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                str = str.trim();
                if (str.startsWith("[") && str.endsWith("]")) {
                    JSONArray ja = JSON.parseArray(str);
                    return getByteArray(ja, defaultValue);
                } else {
                    String[] sa = str.split(REGEX_SPLIT_NUM);
                    result = new Byte[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getByte(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Integer getInteger(Object obj, Integer defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof Integer || obj.getClass().getName().equals(int.class.getName())) {
            return (Integer) obj;
        } else if (obj instanceof Number) {
            return ((Number) obj).intValue();
        } else if (obj instanceof Boolean || obj.getClass().getName().equals(boolean.class.getName())) {
            return ((Boolean) obj) ? 1 : 0;
        } else if (obj instanceof Date) {
            return Long.valueOf(((Date) obj).getTime()).intValue();
        } else if (isOracleTimeStamp(obj)) {
            Date date = getDate(obj, null);
            return getInteger(date, defaultValue);
        } else {
            try {
                String strValue = obj.toString();
                strValue = strValue.replace(",", "");
                if (strValue.length() == 0) {
                    return defaultValue;
                } else if (strValue.indexOf(".") != -1) {
                    return getInteger(getDouble(strValue, null), defaultValue);
                } else {
                    return Integer.parseInt(strValue);
                }
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    public static int[] getIntegers(Object obj, int[] defaultValue) {
        int[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof int[]) {
                result = (int[]) obj;
            } else if (obj instanceof Integer[]) {
                Integer[] a = (Integer[]) obj;
                result = new int[a.length];
                for (int i = 0; i < a.length; i++) {
                    result[i] = a[i];
                }
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new int[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getInteger(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new int[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getInteger(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new int[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getInteger(ja.get(i), null);
                }
            } else {
                result = getIntegers(getIntegerArray(obj, null), defaultValue);
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Integer[] getIntegerArray(Object obj, Integer[] defaultValue) {
        Integer[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof Integer[]) {
                result = (Integer[]) obj;
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new Integer[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getInteger(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new Integer[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getInteger(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new Integer[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getInteger(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                str = str.trim();
                if (str.startsWith("[") && str.endsWith("]")) {
                    JSONArray ja = JSON.parseArray(str);
                    return getIntegerArray(ja, defaultValue);
                } else {
                    String[] sa = str.split(REGEX_SPLIT_NUM);
                    result = new Integer[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getInteger(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Long getLong(Object obj, Long defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof Long || obj.getClass().getName().equals(long.class.getName())) {
            return (Long) obj;
        } else if (obj instanceof Number) {
            return ((Number) obj).longValue();
        } else if (obj instanceof Boolean || obj.getClass().getName().equals(boolean.class.getName())) {
            return ((Boolean) obj) ? 1L : 0L;
        } else if (obj instanceof Date) {
            return ((Date) obj).getTime();
        } else if (isOracleTimeStamp(obj)) {
            Date date = getDate(obj, null);
            return getLong(date, defaultValue);
        } else {
            try {
                String strValue = obj.toString();
                strValue = strValue.replace(",", "");
                if (strValue.length() == 0) {
                    return defaultValue;
                } else if (strValue.indexOf(".") != -1) {
                    return getLong(getDouble(strValue, null), defaultValue);
                } else {
                    return Long.parseLong(strValue);
                }
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    public static long[] getLongs(Object obj, long[] defaultValue) {
        long[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof long[]) {
                result = (long[]) obj;
            } else if (obj instanceof Long[]) {
                Long[] a = (Long[]) obj;
                result = new long[a.length];
                for (int i = 0; i < a.length; i++) {
                    result[i] = a[i];
                }
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new long[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getLong(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new long[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getInteger(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new long[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getInteger(ja.get(i), null);
                }
            } else {
                result = getLongs(getLongArray(obj, null), defaultValue);
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Long[] getLongArray(Object obj, Long[] defaultValue) {
        Long[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof Long[]) {
                result = (Long[]) obj;
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new Long[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getLong(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new Long[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getLong(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new Long[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getLong(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                str = str.trim();
                if (str.startsWith("[") && str.endsWith("]")) {
                    JSONArray ja = JSON.parseArray(str);
                    return getLongArray(ja, defaultValue);
                } else {
                    String[] sa = str.split(REGEX_SPLIT_NUM);
                    result = new Long[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getLong(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Float getFloat(Object obj, Float defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof Float || obj.getClass().getName().equals(float.class.getName())) {
            return (Float) obj;
        } else if (obj instanceof Number) {
            return ((Number) obj).floatValue();
        } else if (obj instanceof Boolean || obj.getClass().getName().equals(boolean.class.getName())) {
            return ((Boolean) obj) ? 1f : 0f;
        } else if (obj instanceof Date) {
            return Long.valueOf(((Date) obj).getTime()).floatValue();
        } else if (isOracleTimeStamp(obj)) {
            Date date = getDate(obj, null);
            return getFloat(date, defaultValue);
        } else if (obj instanceof String) {
            String strValue = (String) obj;
            if (strValue.length() == 0) {
                return defaultValue;
            } else {
                return Float.parseFloat(strValue.replace(",", ""));
            }
        } else {
            try {
                return Float.parseFloat(obj.toString());
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    public static float[] getFloats(Object obj, float[] defaultValue) {
        float[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof float[]) {
                result = (float[]) obj;
            } else if (obj instanceof Float[]) {
                Float[] a = (Float[]) obj;
                result = new float[a.length];
                for (int i = 0; i < a.length; i++) {
                    result[i] = a[i];
                }
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new float[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getFloat(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new float[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getFloat(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new float[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getFloat(ja.get(i), null);
                }
            } else {
                result = getFloats(getFloatArray(obj, null), defaultValue);
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Float[] getFloatArray(Object obj, Float[] defaultValue) {
        Float[] result = defaultValue;
        try {
            if (obj == null) {
                return defaultValue;
            } else if (obj instanceof Float[]) {
                result = (Float[]) obj;
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new Float[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getFloat(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new Float[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getFloat(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new Float[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getFloat(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                str = str.trim();
                if (str.startsWith("[") && str.endsWith("]")) {
                    JSONArray ja = JSON.parseArray(str);
                    return getFloatArray(ja, defaultValue);
                } else {
                    String[] sa = str.split(REGEX_SPLIT_NUM);
                    result = new Float[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getFloat(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Double getDouble(Object obj, Double defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof Double || obj.getClass().getName().equals(double.class.getName())) {
            return (Double) obj;
        } else if (obj instanceof Boolean || obj.getClass().getName().equals(boolean.class.getName())) {
            return ((Boolean) obj) ? 1D : 0D;
        } else if (obj instanceof Date) {
            return Long.valueOf(((Date) obj).getTime()).doubleValue();
        } else if (isOracleTimeStamp(obj)) {
            Date date = getDate(obj, null);
            return getDouble(date, defaultValue);
        } else if (obj instanceof String) {
            String strValue = (String) obj;
            if (strValue.length() == 0) {
                return defaultValue;
            } else {
                return Double.parseDouble(strValue.replace(",", ""));
            }
        } else {
            try {
                return Double.parseDouble(obj.toString());
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    public static double[] getDoubles(Object obj, double[] defaultValue) {
        double[] result = defaultValue;
        try {
            if (obj == null) {
                return result;
            } else if (obj instanceof double[]) {
                result = (double[]) obj;
            } else if (obj instanceof Float[]) {
                Float[] a = (Float[]) obj;
                result = new double[a.length];
                for (int i = 0; i < a.length; i++) {
                    result[i] = a[i];
                }
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new double[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getFloat(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new double[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getDouble(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new double[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getDouble(ja.get(i), null);
                }
            } else {
                result = getDoubles(getDoubleArray(obj, null), defaultValue);
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Double[] getDoubleArray(Object obj, Double[] defaultValue) {
        Double[] result = defaultValue;
        try {
            if (obj == null) {
                return result;
            } else if (obj instanceof Double[]) {
                result = (Double[]) obj;
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new Double[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getDouble(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new Double[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getDouble(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new Double[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getDouble(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                str = str.trim();
                if (str.startsWith("[") && str.endsWith("]")) {
                    JSONArray ja = JSON.parseArray(str);
                    return getDoubleArray(ja, defaultValue);
                } else {
                    String[] sa = str.split(REGEX_SPLIT_NUM);
                    result = new Double[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getDouble(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static BigDecimal getBigDecimal(Object obj, BigDecimal defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof BigDecimal) {
            return (BigDecimal) obj;
        } else if (obj instanceof Short || obj.getClass().getName().equals(short.class.getName())) {
            return BigDecimal.valueOf((Short) obj);
        } else if (obj instanceof Byte || obj.getClass().getName().equals(byte.class.getName())) {
            return BigDecimal.valueOf((Byte) obj);
        } else if (obj instanceof Integer || obj.getClass().getName().equals(int.class.getName())) {
            return BigDecimal.valueOf((Integer) obj);
        } else if (obj instanceof Float || obj.getClass().getName().equals(float.class.getName())) {
            return BigDecimal.valueOf((Float) obj);
        } else if (obj instanceof Double || obj.getClass().getName().equals(double.class.getName())) {
            return BigDecimal.valueOf((Double) obj);
        } else if (obj instanceof Long || obj.getClass().getName().equals(long.class.getName())) {
            return BigDecimal.valueOf((Long) obj);
        } else if (obj instanceof Date) {
            return BigDecimal.valueOf(((Date) obj).getTime());
        } else if (isOracleTimeStamp(obj)) {
            Date date = getDate(obj, null);
            return getBigDecimal(date, defaultValue);
        } else if (obj instanceof Number) {
            return BigDecimal.valueOf(((Number) obj).doubleValue());
        } else if (obj instanceof String) {
            String strValue = (String) obj;
            if (strValue.length() == 0) {
                return defaultValue;
            } else {
                return new BigDecimal(strValue.replace(",", ""));
            }
        } else {
            return defaultValue;
        }
    }

    public static BigDecimal[] getBigDecimalArray(Object obj, BigDecimal[] defaultValue) {
        BigDecimal[] result = defaultValue;
        try {
            if (obj == null) {
                return result;
            } else if (obj instanceof BigDecimal[]) {
                result = (BigDecimal[]) obj;
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new BigDecimal[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getBigDecimal(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new BigDecimal[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getBigDecimal(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new BigDecimal[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getBigDecimal(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                str = str.trim();
                if (str.startsWith("[") && str.endsWith("]")) {
                    JSONArray ja = JSON.parseArray(str);
                    return getBigDecimalArray(ja, defaultValue);
                } else {
                    String[] sa = str.split(REGEX_SPLIT_NUM);
                    result = new BigDecimal[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getBigDecimal(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Date getDate(Object obj, Date defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof Date) {
            return (Date) obj;
        } else if (obj instanceof Number) {
            Date date = Calendar.getInstance().getTime();
            date.setTime(((Number) obj).longValue());
            return date;
        } else if (isOracleTimeStamp(obj)) {
            return toOracleTimeStamp(obj, defaultValue);
        } else {
            String strDate = obj.toString();
            if (StringUtils.isNumeric(strDate)) {
                return getDate(getLong(obj, null), null);
            }
            try {
                return DateUtil.parse(obj.toString());
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    private static Date toOracleTimeStamp(Object obj, Date defaultValue) {
        try {
            initOracleTimeStampMethod();
            if (OracleTimeStampMethod != null) {
                Timestamp ts = (Timestamp) OracleTimeStampMethod.invoke(obj);
                return ts;
            } else {
                return getDate(obj.toString(), defaultValue);
            }
        } catch (Exception e) {
            return defaultValue;
        }
    }

    private static void initOracleTimeStampMethod() {
        if (OracleTimeStampMethod == null) {
            try {
                Class<?> cls = Class.forName("oracle.sql.TIMESTAMP");
                OracleTimeStampMethod = cls.getMethod("timestampValue");
            } catch ( Exception e) {
                log.error("", e);
            }
        }
    }

    public static Date[] getDateArray(Object obj, Date[] defaultValue) {
        Date[] result = defaultValue;
        try {
            if (obj == null) {
                return result;
            } else if (obj instanceof Date[]) {
                return (Date[]) obj;
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new Date[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getDate(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new Date[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getDate(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new Date[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getDate(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                if (str.indexOf("[") != -1 && str.indexOf("]") != -1) {
                    JSONArray ja = JSON.parseArray(str);
                    result = new Date[ja.size()];
                    for (int i = 0; i < ja.size(); i++) {
                        result[i] = getDate(ja.get(i), null);
                    }
                } else {
                    String[] sa = str.split(",");
                    result = new Date[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getDate(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static String getString(Object obj, String defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else if (obj instanceof String) {
            return (String) obj;
        } else if (obj instanceof Blob) {
            return IoUtil.readText((Blob) obj);
        } else if (obj instanceof Clob) {
            return IoUtil.readText((Clob) obj);
        } else if (obj instanceof Date) {
            return DateUtil.formatDateTime((Date) obj);
        } else if (isOracleTimeStamp(obj)) {
            Date date = getDate(obj, null);
            return getString(date, defaultValue);
        } else if (obj instanceof File) {
            return IoUtil.readText((File) obj);
        } else if (obj instanceof InputStream) {
            InputStream inputStream = (InputStream) obj;
            try {
                return IoUtil.readText(inputStream);
            } catch (Exception e) {
                return null;
            } finally {
                IoUtil.closeQuietly(inputStream);
            }
        } else if (obj instanceof Short || obj instanceof Byte || obj instanceof Integer || obj instanceof Long
                || obj.getClass().getName().equals(short.class.getName())
                || obj.getClass().getName().equals(byte.class.getName())
                || obj.getClass().getName().equals(int.class.getName())
                || obj.getClass().getName().equals(long.class.getName())) {
            return obj.toString();
        } else if (obj instanceof Number) {
            return new DecimalFormat("#.###############").format(obj);
        } else {
            return obj.toString();
        }

    }

    public static String[] getStringArray(Object obj, String[] defaultValue) {
        String[] result = defaultValue;
        try {
            if (obj == null) {
                return result;
            } else if (obj instanceof String[]) {
                return (String[]) obj;
            } else if (obj.getClass().isArray()) {
                int length = Array.getLength(obj);
                result = new String[length];
                for (int i = 0; i < length; i++) {
                    result[i] = getString(Array.get(obj, i), null);
                }
            } else if (obj instanceof Collection) {
                Collection<?> col = (Collection<?>) obj;
                result = new String[col.size()];
                Iterator<?> ite = col.iterator();
                int index = 0;
                while (ite.hasNext()) {
                    result[index] = getString(ite.next(), null);
                    index++;
                }
            } else if (obj instanceof JSONArray) {
                JSONArray ja = (JSONArray) obj;
                result = new String[ja.size()];
                for (int i = 0; i < ja.size(); i++) {
                    result[i] = getString(ja.get(i), null);
                }
            } else if (obj instanceof String) {
                String str = (String) obj;
                if (str.indexOf("[") != -1 && str.indexOf("]") != -1) {
                    JSONArray ja = JSON.parseArray(str);
                    result = new String[ja.size()];
                    for (int i = 0; i < ja.size(); i++) {
                        result[i] = getString(ja.get(i), null);
                    }
                } else {
                    String[] sa = str.split(",");
                    result = new String[sa.length];
                    for (int i = 0; i < sa.length; i++) {
                        result[i] = getString(sa[i].trim(), null);
                    }
                }
            }
        } catch (Exception e) {
            log.error("", e);
            result = defaultValue;
        }
        return result;
    }

    public static Object parseValue(Object obj, String javaType) {
        Class<?> javaClass = null;
        try {
            javaClass = Class.forName(javaType);
        } catch (Exception e) {
            log.error("", e);
        }
        if (String.class.getName().equals(javaType)) {
            return getString(obj, null);

        } else if (Byte.class.getName().equals(javaType) || byte.class.getName().equals(javaType)) {
            return getByte(obj, null);

        } else if (Short.class.getName().equals(javaType) || short.class.getName().equals(javaType)) {
            return getShort(obj, null);

        } else if (Integer.class.getName().equals(javaType) || int.class.getName().equals(javaType)) {
            return getInteger(obj, null);

        } else if (Long.class.getName().equals(javaType) || long.class.getName().equals(javaType)) {
            return getLong(obj, null);

        } else if (Float.class.getName().equals(javaType) || float.class.getName().equals(javaType)) {
            return getFloat(obj, null);

        } else if (Double.class.getName().equals(javaType) || double.class.getName().equals(javaType)) {
            return getDouble(obj, null);

        } else if (Boolean.class.getName().equals(javaType) || boolean.class.getName().equals(javaType)) {
            return getBoolean(obj, null);

        } else if (Date.class.getName().equals(javaType)
                || (javaClass != null && Date.class.isAssignableFrom(javaClass))) {
            return getDate(obj, null);

        } else if (BigDecimal.class.getName().equals(javaType)) {
            return getBigDecimal(obj, null);

        } else if (String[].class.getName().equals(javaType)) {
            return getStringArray(obj, null);

        } else if (Byte[].class.getName().equals(javaType)) {
            return getByteArray(obj, null);

        } else if (byte[].class.getName().equals(javaType)) {
            return getBytes(obj, null);

        } else if (Short[].class.getName().equals(javaType)) {
            return getShortArray(obj, null);

        } else if (short[].class.getName().equals(javaType)) {
            return getShorts(obj, null);

        } else if (Integer[].class.getName().equals(javaType)) {
            return getIntegerArray(obj, null);

        } else if (int[].class.getName().equals(javaType)) {
            return getIntegers(obj, null);

        } else if (Long[].class.getName().equals(javaType)) {
            return getLongArray(obj, null);

        } else if (long[].class.getName().equals(javaType)) {
            return getLongs(obj, null);

        } else if (Float[].class.getName().equals(javaType)) {
            return getFloatArray(obj, null);

        } else if (float[].class.getName().equals(javaType)) {
            return getFloats(obj, null);

        } else if (Double[].class.getName().equals(javaType)) {
            return getDoubleArray(obj, null);

        } else if (double[].class.getName().equals(javaType)) {
            return getDoubles(obj, null);

        } else if (BigDecimal[].class.getName().equals(javaType)) {
            return getBigDecimalArray(obj, null);

        } else {
            return obj;
        }
    }

    /**
     * 将数据对象转换为另外一种类型，如果目标类型是源数据类型的子类，则直接强制转换
     *
     * @param <T>
     * @param targetClass 目标类型
     * @param data        源数据对象
     * @return 目标数据对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T parseValue(Class<T> targetClass, Object data) {
        try {
            T t = null;
            if (data == null || targetClass.isAssignableFrom(data.getClass())) {
                t = (T) data;
            } else if (TypeUtil.isSimpleType(data.getClass())) {
                t = (T) parseValue(data, targetClass.getName());
            } else {
                t = targetClass.newInstance();
                BeanUtils.copyProperties(data, t);
            }
            return t;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将数据对象转换为另外一种类型，如果目标类型是源数据类型的子类，则直接强制转换
     *
     * @param <T>
     * @param targetClass      目标类型
     * @param data             源数据对象
     * @param ignoreProperties 忽略的属性
     * @return 目标数据对象
     */
    public static <T> T parseValue(Class<T> targetClass, Object data, String... ignoreProperties) {
        try {
            T t = null;
            if (data == null || targetClass.isAssignableFrom(data.getClass())) {
                t = (T) data;
            } else if (TypeUtil.isSimpleType(data.getClass())) {
                t = (T) parseValue(data, targetClass.getName());
            } else {
                t = targetClass.newInstance();
                BeanUtils.copyProperties(data, t, ignoreProperties);
            }
            return t;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将数据对象转换为另外一种类型，如果目标类型是源数据类型的子类，则直接强制转换
     *
     * @param <T>
     * @param targetClass      目标类型
     * @param data             源数据对象
     * @param ignoreProperties 忽略的属性
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static <T> List<T> parseList(Class<T> targetClass, Object data, String... ignoreProperties) {
        try {
            List<T> list = new ArrayList<T>();
            if (data instanceof Collection) {
                for (Object obj : (Collection) data) {
                    list.add(parseValue(targetClass, obj, ignoreProperties));
                }
            } else if (data != null && data.getClass().isArray()) {
                int length = Array.getLength(data);
                for (int i = 0; i < length; i++) {
                    list.add(parseValue(targetClass, Array.get(data, i), ignoreProperties));
                }
            } else {
                list.add(parseValue(targetClass, data, ignoreProperties));
            }
            return list;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将数据对象转换为另外一种类型，如果目标类型是源数据类型的子类，则直接强制转换
     *
     * @param <T>
     * @param targetClass 目标类型
     * @param data        源数据对象
     * @param map         属性对应韩国的类
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static <T> List<T> parseList(Class<T> targetClass, Object data, Map<String, Class> map) {
        try {
            List<T> list = new ArrayList<T>();
            if (data instanceof Collection) {
                for (Object obj : (Collection) data) {
                    Object o = parseWithProperties(targetClass, map, obj);
                    list.add((T) o);
                }
            } else if (data != null && data.getClass().isArray()) {
                int length = Array.getLength(data);
                for (int i = 0; i < length; i++) {
                    Object o = parseWithProperties(targetClass, map, Array.get(data, i));
                    list.add((T) o);
                }
            } else {
                Object o = parseWithProperties(targetClass, map, data);
                list.add((T) o);
            }
            return list;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static <T> Object parseWithProperties(Class<T> targetClass, Map<String, Class> map, Object obj) {
        Object o = parseValue(targetClass, obj, map.keySet().toArray(new String[0]));
        for (Map.Entry<String, Class> entry : map.entrySet()) {
            Object property = getPropertyValue(obj, entry.getKey());
            if (property != null) {
                o = setValueExist(o, entry.getKey(), (property instanceof Collection || property.getClass().isArray()) ?
                        parseList(entry.getValue(), property) : parseValue(entry.getValue(), property));
            }
        }
        return o;
    }

    /**
     * 将数据对象转换为另外一种类型，如果目标类型是源数据类型的子类，则直接强制转换
     *
     * @param <T>
     * @param targetClass 目标类型
     * @param data        源数据对象
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static <T> T[] parseArray(Class<T> targetClass, Object data) {
        try {
            T[] arr = null;
            if (data == null) {
                arr = (T[]) Array.newInstance(targetClass, 0);
            } else if (data instanceof Collection) {
                Collection collections = (Collection) data;
                int length = collections.size();
                arr = (T[]) Array.newInstance(targetClass, length);
                int index = 0;
                for (Object obj : collections) {
                    arr[index] = parseValue(targetClass, obj);
                    index++;
                }
            } else if (data.getClass().isArray()) {
                int length = Array.getLength(data);
                arr = (T[]) Array.newInstance(targetClass, length);
                for (int i = 0; i < length; i++) {
                    arr[i] = parseValue(targetClass, Array.get(data, i));
                }
            } else {
                arr = (T[]) Array.newInstance(targetClass, 1);
                arr[0] = parseValue(targetClass, data);
            }
            return arr;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @SuppressWarnings("rawtypes")
    public static Map<String, Object> toSimpleDataMap(Object obj) {
        if (obj == null || TypeUtil.isSimpleType(obj.getClass())) {
            return null;
        }

        Map<String, Object> map = new HashMap<String, Object>();
        if (obj instanceof Collection) {
            Collection<?> collections = (Collection<?>) obj;
            if (collections.size() > 0) {
                map = toSimpleDataMap(collections.iterator().next());
            }

        } else if (obj.getClass().isArray()) {
            int length = Array.getLength(obj);
            if (length > 0) {
                map = toSimpleDataMap(Array.get(obj, 0));
            }

        } else if (obj instanceof Map) {
            Map tmp = (Map) obj;
            for (Object objKey : tmp.keySet()) {
                String key = getString(objKey, null);
                Object value = tmp.get(objKey);
                if (value == null) {
                    map.put(key, null);
                } else if (TypeUtil.isSimpleType(value.getClass())) {
                    map.put(key, value);
                }
            }

        } else if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            for (String key : json.keySet()) {
                Object value = json.get(key);
                if (value == null) {
                    map.put(key, null);
                } else if (TypeUtil.isSimpleType(value.getClass())) {
                    map.put(key, value);
                }
            }

        } else {
            Class<?> cls = obj.getClass();
            Map<String, Method> methodMap = getGetterMap(cls.getMethods());
            Map<String, Field> fieldMap = getFieldMap(cls.getFields());
            map.putAll(getValueMap(obj, methodMap, fieldMap));

        }

        return map;
    }

    public static List<Map<String, Object>> toSimpleDataMapList(Collection<?> collections) {
        if (collections == null) {
            return null;
        }
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        if (collections.size() == 0) {
            return list;
        }

        Map<String, Map<String, Method>> clsMethodMap = new HashMap<String, Map<String, Method>>();
        Map<String, Map<String, Field>> clsFieldMap = new HashMap<String, Map<String, Field>>();

        for (Object obj : collections) {
            if (obj == null) {
                continue;
            }
            if (obj instanceof Map) {
                list.add(toSimpleDataMap(obj));
            } else {
                Class<?> cls = obj.getClass();
                if (!clsMethodMap.containsKey(cls.getName())) {
                    clsMethodMap.put(cls.getName(), getGetterMap(cls.getMethods()));
                }
                if (!clsFieldMap.containsKey(cls.getName())) {
                    clsFieldMap.put(cls.getName(), getFieldMap(cls.getFields()));
                }

                Map<String, Method> methodMap = clsMethodMap.get(cls.getName());
                Map<String, Field> fieldMap = clsFieldMap.get(cls.getName());
                list.add(getValueMap(obj, methodMap, fieldMap));
            }
        }

        return list;
    }

    private static Map<String, Object> getValueMap(Object obj, Map<String, Method> methodMap,
                                                   Map<String, Field> fieldMap) {
        Map<String, Object> map = new HashMap<String, Object>();

        for (Map.Entry<String, Method> entry : methodMap.entrySet()) {
            Method method = entry.getValue();
            try {
                map.put(entry.getKey(), method.invoke(obj));
            } catch (Exception e) {
                log.error("", e);
            }
        }

        for (Map.Entry<String, Field> entry : fieldMap.entrySet()) {
            if (methodMap.containsKey(entry.getKey())) {
                continue;
            }
            Field field = entry.getValue();
            try {
                map.put(entry.getKey(), field.get(obj));
            } catch (Exception e) {
                log.error("", e);
            }
        }

        return map;
    }

    private static Method getGetMethod(Method[] methods, String methodKey) {
        if (methods == null || methods.length == 0 || methodKey == null || methodKey.length() == 0) {
            return null;
        }
        for (Method method : methods) {
            // 存在多个参数，则返回
            Class<?>[] types = method.getParameterTypes();
            if (types != null && types.length > 0) {
                continue;
            }
            String methodName = method.getName();
            if (methodName.toLowerCase().endsWith("get" + methodKey.toLowerCase())) {
                return method;
            }
            if (methodName.toLowerCase().endsWith("is" + methodKey.toLowerCase())
                    && (boolean.class.getName().equals(method.getReturnType().getName())
                    || Boolean.class.getName().equals(method.getReturnType().getName()))
            ) {
                return method;
            }

        }

        return null;
    }

    private static Map<String, Method> getGetterMap(Method[] methods) {
        Map<String, Method> map = new HashMap<String, Method>();
        if (methods != null) {
            for (Method method : methods) {
                int modifiers = method.getModifiers();
                if (Modifier.isStatic(modifiers)) {
                    continue;
                }
                if (method.getParameterTypes() != null && method.getParameterTypes().length > 0) {
                    continue;
                }
                if (method.getReturnType() == null) {
                    continue;
                }
                if (method.getName().startsWith("get")) {
                    String name = method.getName().substring(3);
                    name = name.substring(0, 1).toLowerCase() + name.substring(1);
                    map.put(name, method);

                } else if (method.getName().startsWith("is") && (boolean.class.getName().equals(method.getReturnType().getName())
                        || Boolean.class.getName().equals(method.getReturnType().getName()))) {
                    String name = method.getName().substring(2);
                    name = name.substring(0, 1).toLowerCase() + name.substring(1);
                    map.put(name, method);
                }
            }
        }
        return map;
    }

    private static Map<String, Field> getFieldMap(Field[] fields) {
        Map<String, Field> map = new HashMap<String, Field>();
        if (fields != null) {
            for (Field field : fields) {
                int modifiers = field.getModifiers();
                if (Modifier.isStatic(modifiers)) {
                    continue;
                }
                map.put(field.getName(), field);
            }
        }

        return map;
    }

    private static Field getField(Field[] fields, String fieldName) {
        if (fields == null || fields.length == 0 || fieldName == null || fieldName.length() == 0) {
            return null;
        }
        for (Field field : fields) {
            if (field.getName().equals(fieldName)
                    && !Modifier.isStatic(field.getModifiers())) {
                return field;
            }
        }
        return null;
    }

    @SuppressWarnings("rawtypes")
    public static Object getPropertyValue(Object obj, String key) {
        if (obj == null || key == null || key.length() == 0) {
            return null;
        }

        if (obj instanceof Map) {
            return ((Map) obj).get(key);

        } else if (obj instanceof Dictionary) {
            return ((Dictionary) obj).get(key);

        } else if (obj instanceof JSONObject) {
            return ((JSONObject) obj).get(key);

        } else if (TypeUtil.isSimpleType(obj.getClass())) {
            return null;

        } else {
            Class<?> cls = obj.getClass();
            Method getMethod = getGetMethod(cls.getMethods(), key);
            if (getMethod != null) {
                try {
                    return getMethod.invoke(obj);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }

            Field field = getField(cls.getFields(), key);
            if (field != null) {
                try {
                    return field.get(obj);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }

            return null;
        }
    }

    public static <T> T[] toArray(Class<T> cls, Collection<T> collections) {
        return CollectionUtil.toArray(cls, collections);
    }

    public static <T> T[] toArray(Class<T> cls, Object obj) {
        return CollectionUtil.toArray(cls, obj);
    }

    public static <T> List<T> toList(Class<T> cls, T[] array) {
        return CollectionUtil.toList(cls, array);
    }

    public static <T> List<T> toList(Class<T> cls, Object obj) {
        return CollectionUtil.toList(cls, obj);
    }

    public static Object decode(Object checkValue, Object... objects) {
        if (checkValue == null) {
            return null;
        }
        int size = objects.length / 2;
        int mode = objects.length % 2;
        Object v = mode == 0 ? null : objects[objects.length - 1];
        for (int i = 0; i < size; i++) {
            if (checkValue.equals(objects[i])) {
                v = objects[i * 2 + 1];
            }
        }
        return v;
    }

    /**
     * 获取简单数据映射列表
     *
     * @param list 一个简单对象列表
     * @return 属性/值的映射列表
     */
    @SuppressWarnings("rawtypes")
    public static List<Map<String, Object>> listSimpleDataMap(List<?> list) {
        List<Map<String, Object>> rst = new ArrayList<Map<String, Object>>();
        Map<String, Method> methodMap = null;
        for (Object obj : list) {
            Map<String, Object> map = new HashMap<String, Object>();
            if (obj == null) {
                rst.add(map);
                continue;
            } else if (obj instanceof Map) {
                Map tmp = (Map) obj;
                for (Object objKey : tmp.keySet()) {
                    String key = getString(objKey, null);
                    Object value = tmp.get(objKey);
                    if (value == null) {
                        map.put(key, null);
                    } else if (TypeUtil.isSimpleType(value.getClass())) {
                        map.put(key, value);
                    }
                }
            } else {
                if (methodMap == null) {
                    methodMap = getSimpleTypePropertyGetMethodMap(obj.getClass());
                }
                for (Map.Entry<String, Method> entry : methodMap.entrySet()) {
                    try {
                        map.put(entry.getKey(), entry.getValue().invoke(obj));
                    } catch (Exception e) {
                        log.error("", e);
                    }
                }
            }
            rst.add(map);
        }
        return rst;
    }

    /**
     * 获取类中简单类型属性的get方法
     *
     * @param cls 类
     * @return 简单类型的属性和方法映射
     */
    public static Map<String, Method> getSimpleTypePropertyGetMethodMap(Class<?> cls) {
        Map<String, Method> methodMap = new HashMap<String, Method>();
        Method[] methods = cls.getMethods();
        if (methods == null || methods.length == 0) {
            return methodMap;
        }
        for (Method method : methods) {
            int mod = method.getModifiers();
            if (!Modifier.isPublic(mod)
                    || Modifier.isStatic(mod)
                    || Modifier.isFinal(mod)
                    || !TypeUtil.isSimpleType(method.getReturnType())
                    || hasParameter(method)) {
                continue;
            }
            String name = method.getName();
            if (name.startsWith("get") && name.length() > 3) {
                name = name.substring(3, 4).toLowerCase() + name.substring(4);
                methodMap.put(name, method);
            } else if (name.startsWith("is") && name.length() > 2) {
                name = name.substring(2, 3).toLowerCase() + name.substring(3);
                methodMap.put(name, method);
            }
        }
        return methodMap;
    }

    private static boolean hasParameter(Method method) {
        Class<?>[] types = method.getParameterTypes();
        if (types != null && types.length > 0)
            return true;
        return false;
    }

    public static String blob2String(Blob blob) {
        return IoUtil.readText(blob);
    }

    public static String blob2String(Blob blob, String charsetName) {
        return IoUtil.readText(blob, charsetName);
    }

    public static byte[] string2BlobByte(String content) {
        return string2BlobByte(content, null);
    }

    public static byte[] string2BlobByte(String content, String charsetName) {
        if (content == null || content.length() == 0) {
            return null;
        } else {
            try {
                if (charsetName == null || charsetName.length() == 0) {
                    charsetName = IoUtil.Default_Charset;
                }
                return content.getBytes(charsetName);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static String blobByte2String(byte[] bytes) {
        return blobByte2String(bytes, null);
    }

    public static String blobByte2String(byte[] bytes, String charsetName) {
        if (bytes == null) {
            return null;
        } else if (bytes.length == 0) {
            return StringUtils.EMPTY;
        } else {
            try {
                if (charsetName == null || charsetName.length() == 0) {
                    charsetName = IoUtil.Default_Charset;
                }
                return new String(bytes, charsetName);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @SuppressWarnings("rawtypes")
    public static Map<String, Object> getMap(Object value) {
        if (value == null) {
            return new HashMap<String, Object>();
        }

        Map<String, Object> map = new HashMap<String, Object>();
        if (value instanceof Map) {
            for (Object key : ((Map) value).keySet()) {
                map.put(key.toString(), ((Map) value).get(key));
            }
        } else {
            Method[] methods = value.getClass().getDeclaredMethods();
            for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                try {
                    if (!Modifier.isPublic(method.getModifiers()) || method.getParameterTypes().length > 0) {
                        continue;
                    }

                    String name = method.getName();
                    if (name.startsWith("get") && name.length() > 3) {
                        name = name.substring(3, 4).toLowerCase() + name.substring(4, name.length());
                        map.put(name, method.invoke(value));
                    } else if (name.startsWith("is") && name.length() > 2) {
                        name = name.substring(2, 3).toLowerCase() + name.substring(3, name.length());
                        map.put(name, method.invoke(value));
                    }
                } catch (Exception e) {
                    log.error("", e);
                }
            }
        }
        return map;
    }

    /**
     * 设置已存在对象的值
     *
     * @param obj
     * @param propertyName
     * @param value
     */
    public static Object setValueExist(Object obj, String propertyName,
                                       Object value) {

        try {
            String firstLetter = propertyName.substring(0, 1).toUpperCase();
            String lastLetter = propertyName.substring(1).toLowerCase();
            String setName = "set" + firstLetter + lastLetter;

            Field field = getField(obj, propertyName);
            Method setMethod = getSetMethod(obj, setName, field);
            if (setMethod == null) {
                firstLetter = propertyName.substring(0, 1).toUpperCase();
                lastLetter = propertyName.substring(1);
                String setName2 = "set" + firstLetter + lastLetter;
                if (!setName2.equals(setName)) {
                    setMethod = getSetMethod(obj, setName2, field);
                }
            }
            if (setMethod == null)
                return obj;
            else {
                if (field.getType().equals(Long.class) || field.getType().equals(long.class)) {
                    setLongValue(obj, value, setMethod);
                } else if (field.getType().equals(Double.class) || field.getType().equals(double.class)) {
                    setDoubleValue(obj, value, setMethod);
                } else if (field.getType().equals(BigDecimal.class)) {
                    setBigDecimalValue(obj, value, setMethod);

                } else if (field.getType().equals(Short.class) || field.getType().equals(short.class)) {
                    setShortValue(obj, value, setMethod);

                } else if (field.getType().equals(Byte.class) || field.getType().equals(byte.class)) {
                    setByteValue(obj, value, setMethod);

                } else if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) {
                    setIntegerValue(obj, value, setMethod);
                } else if (field.getType().equals(Boolean.class) || field.getType().equals(boolean.class)) {
                    setBooleanValue(obj, value, setMethod);
                } else if (field.getType().equals(Class.forName("java.util.Date"))) {
                    setDateValue(obj, value, setMethod);
                } else if (field.getType().equals(Class.forName("java.util.List")) && setMethod != null) {
                    setMethod.invoke(obj, value);
                } else {
                    Object objType = field.getType().newInstance();
                    objType = value;
                    if (setMethod != null) {
                        setMethod.invoke(obj, new Object[]{objType});
                    }
                }
            }
            return obj;
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }

    private static Field getField(Object obj, String propertyName) throws NoSuchFieldException {
        Field field = null;
        try {
            field = obj.getClass().getDeclaredField(
                    propertyName);
        } catch (Exception e) {
            log.error("", e);
        }
        if (field == null) {
            field = obj.getClass().getDeclaredField(
                    propertyName.toLowerCase());
        }
        return field;
    }

    private static Method getSetMethod(Object obj, String setName, Field field) {
        try {
            return obj.getClass().getMethod(setName,
                    field.getType());
        } catch (Exception e) {
            log.error("setMethod is null, setName : {}", setName, e);
        }
        return null;
    }

    private static void setDateValue(Object obj, Object value, Method setMethod) throws IllegalAccessException, InvocationTargetException {
        if (value != null && !value.toString().equals("")) {
            if (value.getClass().getName().equals("java.util.Date")
                    || value.getClass().getName()
                    .equals("java.sql.Timestamp")) {
                setMethod.invoke(obj, new Object[]{value});
            } else {
                setMethod.invoke(obj, DateUtil.parse((String) value));
            }
        } else {
            setMethod.invoke(obj, null);
        }
    }

    private static void setBooleanValue(Object obj, Object value, Method setMethod) throws IllegalAccessException, InvocationTargetException {
        if (value == null || value.equals("") || value.equals("null")) {
            setMethod.invoke(obj, null);
        } else if (value.equals("true")) {
            setMethod.invoke(obj, 1L);
        } else if (value.equals("false")) {
            setMethod.invoke(obj, 1L);
        } else if (!value.toString().equals("")
                && value.getClass().getName()
                .equals("java.lang.String")) {
            setMethod.invoke(obj,
                    Long.valueOf(value.toString()));
        } else if (value instanceof Number) {
            setMethod.invoke(obj, ((Number) value).longValue());
        } else {

            setMethod.invoke(obj, new Object[]{value});
        }
    }

    private static void setIntegerValue(Object obj, Object value, Method setMethod) throws IllegalAccessException, InvocationTargetException {
        if (value == null || value.equals("") || value.equals("null")) {
            setMethod.invoke(obj, null);
        } else if (value.equals("true")) {
            setMethod.invoke(obj, 1);
        } else if (value.equals("false")) {
            setMethod.invoke(obj, 0);
        } else if (!value.toString().equals("")
                && value.getClass().getName()
                .equals("java.lang.String")) {
            setMethod.invoke(obj,
                    Integer.valueOf(value.toString()));
        } else if (value instanceof Number) {
            setMethod.invoke(obj, ((Number) value).intValue());
        } else {

            setMethod.invoke(obj, new Object[]{value});
        }
    }

    private static void setByteValue(Object obj, Object value, Method setMethod) throws IllegalAccessException, InvocationTargetException {
        if (value == null || value.equals("") || value.equals("null")) {
            setMethod.invoke(obj, null);
        } else if (value.equals("true")) {
            setMethod.invoke(obj, 1);
        } else if (value.equals("false")) {
            setMethod.invoke(obj, 0);
        } else if (!value.toString().equals("")
                && value.getClass().getName()
                .equals("java.lang.String")) {
            setMethod.invoke(obj,
                    Byte.parseByte(value.toString()));
        } else if (value instanceof Number) {
            setMethod.invoke(obj, ((Number) value).byteValue());
        } else {
            setMethod.invoke(obj, new Object[]{value});
        }
    }

    private static void setShortValue(Object obj, Object value, Method setMethod) throws IllegalAccessException, InvocationTargetException {
        if (value == null || value.equals("") || value.equals("null")) {
            setMethod.invoke(obj, null);
        } else if (value.equals("true")) {
            setMethod.invoke(obj, 1);
        } else if (value.equals("false")) {
            setMethod.invoke(obj, 0);
        } else if (!value.toString().equals("")
                && value.getClass().getName()
                .equals("java.lang.String")) {
            setMethod.invoke(obj,
                    Short.parseShort(value.toString()));
        } else if (value instanceof Number) {
            setMethod.invoke(obj, ((Number) value).shortValue());
        } else {
            setMethod.invoke(obj, new Object[]{value});
        }
    }

    private static void setBigDecimalValue(Object obj, Object value, Method setMethod) throws IllegalAccessException, InvocationTargetException {
        if (value == null || value.equals("") || value.equals("null")) {
            setMethod.invoke(obj, null);
        } else if (value.equals("true")) {
            setMethod.invoke(obj, 1);
        } else if (value.equals("false")) {
            setMethod.invoke(obj, 0);
        } else if (!value.toString().equals("")
                && value.getClass().getName()
                .equals("java.lang.String")) {
            setMethod.invoke(obj,
                    BigDecimal.valueOf(Double.parseDouble(value.toString())));
        } else if (value instanceof Number) {
            setMethod.invoke(obj, BigDecimal.valueOf(((Number) value).doubleValue()));
        } else {
            setMethod.invoke(obj, new Object[]{value});
        }
    }

    private static void setDoubleValue(Object obj, Object value, Method setMethod) throws IllegalAccessException, InvocationTargetException {
        if (value == null || value.toString().isEmpty()) {
            setMethod.invoke(obj, null);
        } else {
            setMethod.invoke(obj,
                    Double.valueOf(value.toString()));
        }
    }

    private static void setLongValue(Object obj, Object value, Method setMethod) throws IllegalAccessException, InvocationTargetException {
        if (value != null && !value.toString().equals("")) {
            setMethod.invoke(obj,
                    Long.valueOf(value.toString()));
        } else {
            setMethod.invoke(obj, Long.valueOf(0));
        }
    }


    public static Object sum(Object obj1, Object obj2) {
        if (obj1 instanceof Integer) {
            return (Integer) obj1 + (Integer) obj2;
        } else if (obj1 instanceof Long) {
            return (Long) obj1 + (Long) obj2;
        } else if (obj1 instanceof Double) {
            return (Double) obj1 + (Double) obj2;
        } else if (obj1 instanceof Float) {
            return (Float) obj1 + (Float) obj2;
        } else if (obj1 instanceof Byte) {
            return (Byte) obj1 + (Byte) obj2;
        } else if (obj1 instanceof Short) {
            return (Short) obj1 + (Short) obj2;
        } else if (obj1 instanceof BigDecimal) {
            BigDecimal ret = null;
            if (obj2 instanceof Integer) {
                ret = BigDecimal.valueOf(((Number) obj2).doubleValue());
            } else {
                ret = (BigDecimal) obj2;
            }
            return BigDecimal.valueOf(((BigDecimal) obj1).doubleValue() + (ret).doubleValue());
        }
        return String.valueOf(obj1) + String.valueOf(obj2);
    }
}
